package mqtt

import (
	"fmt"
	"log"
	"strings"
	"time"

	"goEmqxToDb/config"

	MQTT "github.com/eclipse/paho.mqtt.golang"
)

// Client MQTT客户端
type Client struct {
	client MQTT.Client
	tasks  []config.Task
}

// NewClient 创建新的MQTT客户端
func NewClient() (*Client, error) {
	log.Println("=== 开始创建MQTT客户端 ===")
	log.Println("正在重新读取配置文件...")

	mqttConfig, err := config.GetMQTTConfig()
	if err != nil {
		return nil, fmt.Errorf("获取MQTT配置失败: %v", err)
	}

	tasks, err := config.GetTasks()
	if err != nil {
		return nil, fmt.Errorf("获取任务配置失败: %v", err)
	}

	// 创建MQTT客户端选项
	opts := MQTT.NewClientOptions()
	opts.AddBroker(fmt.Sprintf("tcp://%s:%d", mqttConfig.Host, mqttConfig.Port))

	// 设置客户端ID
	clientID := fmt.Sprintf("goEmqxToDb_%d", time.Now().Unix())
	opts.SetClientID(clientID)

	// 设置认证信息
	// if mqttConfig.UserValidationEnabled == 1 {
	opts.SetUsername(mqttConfig.Username)
	opts.SetPassword(mqttConfig.Password)
	// }

	// 设置连接参数
	// opts.SetAutoReconnect(true)
	// opts.SetConnectRetry(true)
	// opts.SetConnectRetryInterval(5 * time.Second)
	// opts.SetMaxReconnectInterval(1 * time.Minute)

	// 创建客户端
	client := MQTT.NewClient(opts)

	// 显示当前配置信息
	log.Printf("=== 当前MQTT配置 ===")
	log.Printf("服务器地址: %s:%d", mqttConfig.Host, mqttConfig.Port)
	log.Printf("用户名: %s", mqttConfig.Username)
	log.Printf("客户端ID: %s", clientID)
	log.Printf("任务数量: %d", len(tasks))
	for i, task := range tasks {
		log.Printf("任务%d: %s (项目: %s)", i+1, task.TaskName, task.ProjectIdentifier)
	}
	log.Println("=== 配置信息显示完成 ===")

	return &Client{
		client: client,
		tasks:  tasks,
	}, nil
}

// Connect 连接到MQTT服务器
func (c *Client) Connect() error {
	token := c.client.Connect()
	if token.Wait() && token.Error() != nil {
		return fmt.Errorf("MQTT连接失败: %v", token.Error())
	}
	return nil
}

// Subscribe 订阅主题
func (c *Client) Subscribe(handler MQTT.MessageHandler) error {
	log.Println("=== 开始订阅主题 ===")

	for _, task := range c.tasks {
		for _, groupID := range task.GroupIdentifier {
			// 构建订阅主题: data/projectIdentifier/groupIdentifier/+
			topic := fmt.Sprintf("data/%s/%s/+", task.ProjectIdentifier, groupID)

			log.Printf("正在订阅主题: %s (QoS: %d)", topic, task.QoS)

			token := c.client.Subscribe(topic, byte(task.QoS), func(client MQTT.Client, msg MQTT.Message) {
				log.Printf("=== 收到MQTT消息 ===")
				log.Printf("主题: %s", msg.Topic())
				log.Printf("消息内容: %s", string(msg.Payload()))
				log.Printf("QoS: %d", msg.Qos())
				log.Printf("消息ID: %d", msg.MessageID())
				handler(client, msg)
				log.Printf("=== 消息处理完成 ===")
			})

			if token.Wait() && token.Error() != nil {
				return fmt.Errorf("订阅主题 %s 失败: %v", topic, token.Error())
			}

			log.Printf("成功订阅主题: %s", topic)
		}
	}

	log.Println("=== 主题订阅完成 ===")
	return nil
}

// Disconnect 断开连接
func (c *Client) Disconnect() {
	c.client.Disconnect(250)
	log.Println("MQTT连接已断开")
}

// GetTasks 获取任务配置
func (c *Client) GetTasks() []config.Task {
	return c.tasks
}

// ParseTopic 解析主题，提取projectIdentifier和groupIdentifier
func ParseTopic(topic string) (projectIdentifier, groupIdentifier string, err error) {
	parts := strings.Split(topic, "/")
	if len(parts) != 4 {
		return "", "", fmt.Errorf("无效的主题格式: %s", topic)
	}

	if parts[0] != "data" {
		return "", "", fmt.Errorf("主题必须以 'data' 开头: %s", topic)
	}

	return parts[1], parts[2], nil
}
